#!/bin/bash
# 统计各个TCP连接状态的个数。用于方便排查系统连接负荷问题。

# @Function
# show count of tcp connection stat.
#
# @Usage
#   $ ./tcp-connection-state-counter
#
# @online-doc https://github.com/oldratlee/useful-scripts/blob/dev-2.x/docs/shell.md#-tcp-connection-state-counter
# @author Jerry Lee (oldratlee at gmail dot com)
# @author @sunuslee (sunuslee at gmail dot com)
set -eEuo pipefail

# NOTE: DO NOT declare var PROG as readonly, because its value is supplied by subshell.
PROG="$(basename "$0")"
readonly PROG_VERSION='2.4.0-dev'

################################################################################
# util functions
################################################################################

usage() {
    cat <<EOF
Usage: ${PROG} [OPTION]...
show count of tcp connection stat.

Example:
    ${PROG}

Options:
    -h, --help      display this help and exit
    -V, --version   display version information and exit
EOF
    exit
}

progVersion() {
    echo "$PROG $PROG_VERSION"
    exit
}

################################################################################
# parse options
################################################################################

for a; do
    [[ "-h" == "$a" || "--help" == "$a" ]] && usage
done

for a; do
    [[ "-V" == "$a" || "--version" == "$a" ]] && progVersion
done

################################################################################
# biz logic
################################################################################

# On MacOS, netstat need to using -p tcp to get only tcp output.
uname | grep Darwin -q && option_for_mac="-ptcp"

netstat -tna ${option_for_mac:-} | awk 'NR > 2 {
    ++s[$NF]
}

END {
    # get max length of stat and count
    for(v in s) {
        stat_len = length(v)
        if(stat_len > max_stat_len) max_stat_len = stat_len

        count_len = length(s[v])
        if (count_len > max_count_len) max_count_len = count_len
    }

    for(v in s) {
        printf "%-" max_stat_len "s %" max_count_len "s\n", v, s[v]
    }
}' | sort -nr -k2,2
